<!DOCTYPE html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>Assign resource values to specific days</title>
	<script src="../../codebase/dhtmlxgantt.js?v=7.1.0"></script>
	<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.0">

	<script src="../common/resource_project_assignments.js?v=7.1.0"></script>

	<style>
		html, body {
			padding: 0px;
			margin: 0px;
			height: 100%;
		}

		#gantt_here {
			width:100%;
			height:100%;
		}

		.gantt_grid_scale .gantt_grid_head_cell,
		.gantt_task .gantt_task_scale .gantt_scale_cell {
			font-weight: bold;
			font-size: 14px;
			color: rgba(0, 0, 0, 0.7);
		}

		.resource_marker{
			text-align: center;
		}
		.resource_marker div{
			color: black;
			background: none;
		}

		.resource_marker.resource_cell div{
			font-weight: bold;
			background-color: #d6d6d6;
		}
		.resource_marker.task_cell div {
			cursor: pointer;
		}

		.resource_marker.workday_ok div {
		}


		.resource_marker.workday_over div{
			color: red;
		}


		.owner-label{
			width: 20px;
			height: 20px;
			line-height: 20px;
			font-size: 12px;
			display: inline-block;
			border: 1px solid #cccccc;
			border-radius: 25px;
			background: #e6e6e6;
			color: #6f6f6f;
			margin: 0 3px;
			font-weight: bold;
		}

	</style>
</head>
<body>

<div id="gantt_here"></div>
<script>

	gantt.message({
		text:[
			"Click any cell of the <b>Interior office</b> item down in the resource panel in order to set resource values for specific days"
		].join("<br><br>"),
		expire: -1
	});

	gantt.config.resource_render_empty_cells = true;
	gantt.config.columns = [
		{name: "text", tree: true, width: 200, resize: true},
		{name: "start_date", align: "center", width: 80, resize: true},
		{name: "owner", align: "center", width: 75, label: "Owner", template: function (task) {
			if (task.type == gantt.config.types.project) {
				return "";
			}

			var store = gantt.getDatastore("resource");
			var assignments = gantt.getTaskAssignments(task.id);

			var uniqueResources = {};
			var resourceCount = 0;
			assignments.forEach(function(a){
				if(!uniqueResources[a.resource_id]){
					uniqueResources[a.resource_id] = a.resource_id;
					resourceCount++;
				}
			});

			if(!resourceCount){
				return "Unassigned";
			}else if(resourceCount === 1){
				return store.getItem(assignments[0].resource_id).text;
			}else{
				var result = "";
				for(var i in uniqueResources){
					var owner = store.getItem(uniqueResources[i]);
					if (!owner)
						continue;
					result += "<div class='owner-label' title='" + owner.text + "'>" + owner.text.substr(0, 1) + "</div>";
				}
				return result;
			}
		
			return result;
			}, resize: true
		},
		{name: "duration", width: 60, align: "center"},
		{name: "add", width: 44}
	];

	function getResourceAssignments(resourceId) {
		var assignments;
		var store = gantt.getDatastore(gantt.config.resource_store);
		var resource = store.getItem(resourceId);

		if(resource.$role === "task"){
			assignments = gantt.getResourceAssignments(resource.$resource_id, resource.$task_id);
		}else{
			assignments = gantt.getResourceAssignments(resourceId);
			if(store.eachItem){
				store.eachItem(function(childResource){
					if(childResource.$role !== "task"){
						assignments = assignments.concat(gantt.getResourceAssignments(childResource.id));
					}
				}, resourceId);
			}
		}
		return assignments;
	}

	var resourceConfig = {
		columns: [
			{
				name: "name", label: "Name", tree:true, template: function (resource) {
					return resource.text;
				}
			},
			{
				name: "workload", label: "Workload", template: function (resource) {
					var totalDuration = 0;
					if (resource.$role === "task"){
						gantt.getResourceAssignments(resource.$resource_id, resource.$task_id).forEach(function(a){
							totalDuration += a.value * a.duration;
						});
					}else{
						getResourceAssignments(resource.id).forEach(function (assignment) {
							totalDuration += Number(assignment.value) * assignment.duration;
						});
					}
					return (totalDuration || 0) + "h";
				}
			}
		]
	};

	gantt.templates.resource_cell_class = function(start_date, end_date, resource, tasks, assignments){
		var css = [];
		css.push("resource_marker");

		if(resource.$role === "task"){
			css.push("task_cell");
		}else{
			css.push("resource_cell");
		}

		var sum = assignments.reduce(function(total, assignment){ 
			return total + Number(assignment.value);
		}, 0);

		if (sum <= 8) {
			css.push("workday_ok");
		} else {
			css.push("workday_over");
		}
		return css.join(" ");
	};

	gantt.templates.resource_cell_value = function(start_date, end_date, resource, tasks, assignments){

		if(resource.$role === "task"){
			if(start_date < resource.end_date && end_date > resource.start_date){
				for(var i = 0; i < assignments.length; i++){
					var a = assignments[i];
						return "<div contenteditable data-assignment-cell data-assignment-id='"+a.id+"'"+
						" data-row-id='"+resource.id+"'"+
						" data-task='"+resource.$task_id+"'"+
						" data-start-date='"+gantt.templates.format_date(start_date)+"'"+
						" data-end-date='"+gantt.templates.format_date(end_date)+"'>" + a.value + "</div>"
				}
				return "<div contenteditable data-assignment-cell data-empty "+ 
						" data-row-id='"+resource.id+"'"+
						" data-resource-id='"+resource.$resource_id+"'"+
						" data-task='"+resource.$task_id+"'"+
						" data-start-date='"+gantt.templates.format_date(start_date)+"'"+
						"'  data-end-date='"+gantt.templates.format_date(end_date)+"'>-</div>";
			}

		}else{
			var sum = assignments.reduce(function(total, assignment){ 
				return total + Number(assignment.value);
			}, 0);

			if(sum % 1){
				sum = Math.round(sum * 10)/10;
			}

			if(sum){
				return "<div>" + sum + "</div>";
			}
			return "";
		}

	};

	
	gantt.attachEvent("onGanttReady", function(){
		gantt.event(gantt.$container, "keypress", function(e){
			var target = e.target.closest(".resourceTimeline_cell [data-assignment-cell]");
			if(target){
				if (e.keyCode === 13 || e.keyCode === 27) {
					target.blur();
				}
			}
		});

		gantt.event(gantt.$container, "focusout", function(e){
			var target = e.target.closest(".resourceTimeline_cell [data-assignment-cell]");
			if(target){
				var strValue = (target.innerText || "").trim();
				if(strValue == "-"){
					strValue = "0";
				}
				var value = Number(strValue);
				var rowId = target.getAttribute("data-row-id");
				var assignmentId = target.getAttribute("data-assignment-id");
				var taskId = target.getAttribute("data-task");
				var resourceId = target.getAttribute("data-resource-id");
				var startDate = gantt.templates.parse_date(target.getAttribute("data-start-date"));
				var endDate = gantt.templates.parse_date(target.getAttribute("data-end-date"));

				var assignmentStore = gantt.getDatastore(gantt.config.resource_assignment_store);
				if(isNaN(value)){
					gantt.getDatastore(gantt.config.resource_store).refresh(rowId);
				}else{
					var task = gantt.getTask(taskId);
					if(assignmentId){
						
						var assignment = assignmentStore.getItem(assignmentId);
						if(value === assignment.value){
							return;
						}
						if(assignment.start_date.valueOf() === startDate.valueOf() && assignment.end_date.valueOf() === endDate.valueOf()){
							assignment.value = value;
							if(!value){
								assignmentStore.removeItem(assignment.id);
							}else{
								assignmentStore.updateItem(assignment.id);
							}
						} else {
							var prevChunk = null;

							if(assignment.end_date.valueOf() > endDate.valueOf()){
								var nextChunk = gantt.copy(assignment);
								nextChunk.id = gantt.uid();
								nextChunk.start_date = endDate;
								nextChunk.duration = gantt.calculateDuration({
									start_date: nextChunk.start_date,
									end_date: nextChunk.end_date,
									task: task
								});
								nextChunk.delay = gantt.calculateDuration({
									start_date: task.start_date,
									end_date: nextChunk.start_date,
									task: task
								});
								nextChunk.mode = assignment.mode || "default";
								if(nextChunk.duration !== 0){
									assignmentStore.addItem(nextChunk);
								}
							}

							if(assignment.start_date.valueOf() < startDate.valueOf()){
								assignment.end_date = startDate;
								assignment.duration = gantt.calculateDuration({
									start_date: assignment.start_date,
									end_date: assignment.end_date,
									task: task
								});
								assignment.mode = "fixedDuration";

								if(assignment.duration === 0){
									assignmentStore.removeItem(assignment.id);
								}else{
									assignmentStore.updateItem(assignment.id);
								}
							}else{
								assignmentStore.removeItem(assignment.id);
							}

							if(value){
								assignmentStore.addItem({
									task_id: assignment.task_id,
									resource_id: assignment.resource_id,
									value: value,
									start_date: startDate,
									end_date: endDate,
									duration: gantt.calculateDuration({
										start_date: startDate,
										end_date: endDate,
										task: task
									}),
									delay: gantt.calculateDuration({
										start_date: task.start_date,
										end_date: startDate,
										task: task
									}),
									mode: "fixedDuration"
								});
							}
						}

						gantt.updateTaskAssignments(task.id);
						gantt.updateTask(task.id);
					}else if(value){
						var assignment = {
							task_id: taskId,
							resource_id: resourceId,
							value: value,
							start_date: startDate,
							end_date: endDate,
							duration: gantt.calculateDuration({
								start_date: startDate,
								end_date: endDate,
								task: task
							}),
							delay: gantt.calculateDuration({
								start_date: task.start_date,
								end_date: startDate,
								task: task
							}),
							mode: "fixedDuration"
						};

						assignmentStore.addItem(assignment);
						gantt.updateTaskAssignments(task.id);
						gantt.updateTask(task.id);

					}
				}
			}
		});
	})

	gantt.locale.labels.section_resources = "Owners";
	gantt.config.lightbox.sections = [
		{ name: "description", height: 38, map_to: "text", type: "textarea", focus: true },
		{ name: "resources", type: "resources", map_to: "owner", options: gantt.serverList("people"), default_value: 8},
		{ name: "time", type: "duration", map_to: "auto" }
	];

	gantt.config.resource_store = "resource";
	gantt.config.resource_property = "owner";
	gantt.config.order_branch = true;
	gantt.config.open_tree_initially = true;
	gantt.config.layout = {
		css: "gantt_container",
		rows: [
			{
				cols: [
					{view: "grid", group:"grids", scrollY: "scrollVer"},
					{resizer: true, width: 1},
					{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
					{view: "scrollbar", id: "scrollVer", group:"vertical"}
				],
				gravity:2
			},
			{resizer: true, width: 1},
			{
				config: resourceConfig,
				cols: [
					{view: "resourceGrid", group:"grids", width: 435, scrollY: "resourceVScroll" },
					{resizer: true, width: 1},
					{view: "resourceTimeline", scrollX: "scrollHor", scrollY: "resourceVScroll"},
					{view: "scrollbar", id: "resourceVScroll", group:"vertical"}
				],
				gravity:1
			},
			{view: "scrollbar", id: "scrollHor"}
		]
	};

	var resourcesStore = gantt.createDatastore({
		name: gantt.config.resource_store,
		type: "treeDatastore",
		fetchTasks: true,
		initItem: function (item) {
			item.parent = item.parent || gantt.config.root_id;
			item[gantt.config.resource_property] = item.parent;
			item.open = true;
			return item;
		}
	});
	resourcesStore.attachEvent("onParse", function() {
			var people = [];

			resourcesStore.eachItem(function(res) {
				if (res.$level === 1) {
					var copy = gantt.copy(res);
					copy.key = res.id;
					copy.label = res.text;
					copy.unit = "hours/day";
					people.push(copy);
				}
			});
			gantt.updateCollection("people", people);
		});


	gantt.init("gantt_here");


	resourcesStore.parse([
		{id: 1, text: "QA", parent:null},
		{id: 2, text: "Development", parent:null},
		{id: 3, text: "Sales", parent:null},
		{id: 4, text: "Other", parent:null},
		{id: 5, text: "Unassigned", parent:4},
		{id: 6, text: "John", parent:1, unit: "hours/day" },
		{id: 7, text: "Mike", parent:2, unit: "hours/day" },
		{id: 8, text: "Anna", parent:2, unit: "hours/day" },
		{id: 9, text: "Bill", parent:3, unit: "hours/day" },
		{id: 10, text: "Floe", parent:3, unit: "hours/day" }
	]);

	gantt.createDataProcessor(function(entity, action, data, id){
		console.log(JSON.stringify({
			entity,
			action,
			data,
			id
		}, null, 2));
	});


	gantt.parse({
		data: [

			{
				id: 1,
				text: "Office itinerancy",
				type: "project",
				start_date: "02-04-2019 00:00",
				duration: 17,
				progress: 0.4,
				parent: 0
			},
			{
				id: 2,
				text: "Office facing",
				type: "project",
				start_date: "02-04-2019 00:00",
				duration: 8,
				progress: 0.6,
				parent: "1"
			},
			{
				id: 3,
				text: "Furniture installation",
				type: "project",
				start_date: "11-04-2019 00:00",
				duration: 8,
				parent: "1",
				progress: 0.6,
				owner: []
			},
			{
				id: 4,
				text: "The employee relocation",
				type: "project",
				start_date: "13-04-2019 00:00",
				duration: 5,
				parent: "1",
				progress: 0.5,
				owner: [],
				priority: 3
			},
			{
				id: 5,
				text: "Interior office",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 7,
				parent: "2",
				progress: 0.6,
				owner: [
				{
						resource_id: "6",
						value: 3,
						start_date: "03-04-2019 00:00",
						end_date: "05-04-2019 00:00",
					}],
				priority: 1
			},
			{
				id: 6,
				text: "Air conditioners check",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 7,
				parent: "2",
				progress: 0.6,
				owner: [
				{
						resource_id: "6",
						value: 4,
						delay: 2
					}],
				priority: 2
			},
			{
				id: 7,
				text: "Workplaces preparation",
				type: "task",
				start_date: "12-04-2019 00:00",
				duration: 8,
				parent: "3",
				progress: 0.6,
				owner: [
					{
						resource_id: "10",
						value: 2
					}]
			},
			{
				id: 8,
				text: "Preparing workplaces",
				type: "task",
				start_date: "14-04-2019 00:00",
				duration: 5,
				parent: "4",
				progress: 0.5,
				owner: [
					{
						resource_id: "10",
						value: 4
					},
					{
						resource_id: "9",
						value: 5
					}],
				priority: 1
			},
			{
				id: 9,
				text: "Workplaces importation",
				type: "task",
				start_date: "21-04-2019 00:00",
				duration: 4,
				parent: "4",
				progress: 0.5,
				owner: [
					{
						resource_id: "7",
						value: 3
					}]
			},
			{
				id: 10,
				text: "Workplaces exportation",
				type: "task",
				start_date: "27-04-2019 00:00",
				duration: 3,
				parent: "4",
				progress: 0.5,
				owner: [
					{
						resource_id: "8",
						value: 5
					}],
				priority: 2
			},
			{
				id: 11,
				text: "Product launch",
				type: "project",
				progress: 0.6,
				start_date: "02-04-2019 00:00",
				duration: 13,
				owner: [
					{
						resource_id: "5",
						value: 4
					}],
				parent: 0
			},
			{
				id: 12,
				text: "Perform Initial testing",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 5,
				parent: "11",
				progress: 1,
				owner: [
					{
						resource_id: "7",
						value: 6
					}]
			},
			{
				id: 13,
				text: "Development",
				type: "project",
				start_date: "03-04-2019 00:00",
				duration: 11,
				parent: "11",
				progress: 0.5,
				owner: [
					{
						resource_id: "5",
						value: 2
					}]
			},
			{
				id: 14,
				text: "Analysis",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 6,
				parent: "11",
				owner: [
				],
				progress: 0.8
			},
			{
				id: 15,
				text: "Design",
				type: "project",
				start_date: "03-04-2019 00:00",
				duration: 5,
				parent: "11",
				progress: 0.2,
				owner: [
					{
						resource_id: "5",
						value: 5
					}]
			},
			{
				id: 16,
				text: "Documentation creation",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 7,
				parent: "11",
				progress: 0,
				owner: [
					{
						resource_id: "7",
						value: 2
					}],
				priority: 1
			},
			{
				id: 17,
				text: "Develop System",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 2,
				parent: "13",
				progress: 1,
				owner: [
					{
						resource_id: "8",
						value: 1
					}],
				priority: 2
			},
			{
				id: 25,
				text: "Beta Release",
				type: "milestone",
				start_date: "06-04-2019 00:00",
				parent: "13",
				progress: 0,
				owner: [
					{
						resource_id: "5",
						value: 1
					}],
				duration: 0
			},
			{
				id: 18,
				text: "Integrate System",
				type: "task",
				start_date: "10-04-2019 00:00",
				duration: 2,
				parent: "13",
				progress: 0.8,
				owner: [
					{
						resource_id: "6",
						value: 2
					}],
				priority: 3
			},
			{
				id: 19,
				text: "Test",
				type: "task",
				start_date: "13-04-2019 00:00",
				duration: 4,
				parent: "13",
				progress: 0.2,
				owner: [
					{
						resource_id: "6",
						value: 3
					}]
			},
			{
				id: 20,
				text: "Marketing",
				type: "task",
				start_date: "13-04-2019 00:00",
				duration: 4,
				parent: "13",
				progress: 0,
				owner: [
					{
						resource_id: "8",
						value: 4
					}],
				priority: 1
			},
			{
				id: 21,
				text: "Design database",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 4,
				parent: "15",
				progress: 0.5,
				owner: [
					{
						resource_id: "6",
						value: 5
					}]
			},
			{
				id: 22,
				text: "Software design",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 4,
				parent: "15",
				progress: 0.1,
				owner: [
					{
						resource_id: "8",
						value: 3
					}],
				priority: 1
			},
			{
				id: 23,
				text: "Interface setup",
				type: "task",
				start_date: "03-04-2019 00:00",
				duration: 5,
				parent: "15",
				progress: 0,
				owner: [
					{
						resource_id: "8",
						value: 5
					}],
				priority: 1
			},
			{
				id: 24,
				text: "Release v1.0",
				type: "milestone",
				start_date: "20-04-2019 00:00",
				parent: "11",
				progress: 0,
				owner: [
					{
						resource_id: "5",
						value: 3
					}],
				duration: 0
			}
		],
		links: [


			{
				id: "2",
				source: "2",
				target: "3",
				type: "0"
			},
			{
				id: "3",
				source: "3",
				target: "4",
				type: "0"
			},
			{
				id: "7",
				source: "8",
				target: "9",
				type: "0"
			},
			{
				id: "8",
				source: "9",
				target: "10",
				type: "0"
			},
			{
				id: "16",
				source: "17",
				target: "25",
				type: "0"
			},
			{
				id: "17",
				source: "18",
				target: "19",
				type: "0"
			},
			{
				id: "18",
				source: "19",
				target: "20",
				type: "0"
			},
			{
				id: "22",
				source: "13",
				target: "24",
				type: "0"
			},
			{
				id: "23",
				source: "25",
				target: "18",
				type: "0"
			}

		]
	});
</script>
</body>